#include<iostream>
#include<type_traits>

template<size_t size>
    class Matrix;

template<typename Val,int Num,
    typename = typename std::enable_if< 
        std::is_integral<Val>::value 
        | std::is_floating_point<Val>::value
        >::type>
    void Warshall(Val matrix[Num][Num]){
        // int i,j,k;
        for(int i=0;i<Num;++i){
            for(int j=0;j<Num;++j){
                if(matrix[j][i])
                    for(int k=0;k<Num;k++){
                        matrix[j][k]|=matrix[i][k];
                    }
            }
        }
    }
template<size_t size>
    void Warshall(Matrix<size> &matrix,bool show=false){
        int times=0;
        for(int i=0;i<size;++i){
            for(int j=0;j<size;++j){
                if(matrix.get(j,i)){
                    for(int k=0;k<size;k++){
                        matrix.get(j,k)|=matrix.get(i,k);
                    }
                    if(show){
                        std::cout<<++times<<" times :"<<std::endl;
                        matrix.show();
                    }
                }
            }
        }
    }
template<typename T,int N>
    void showMatrix(T matrix[N][N]){
        for(int i=0;i<N;++i){
            for(int j=0;j<N;++j){
                std::cout<<matrix[i][j]<<' ';
            }std::cout<<std::endl;
        }
    }

struct edge{
    int beg,end,weight=1;
    edge(int b,int e,int w=1):beg(b),end(e),weight(w){}
};
template<size_t size>
class Matrix{//adjast
    protected:
        int matrix[size][size];
        // Vec<T>nodes;//sort as added sequence
    public:
        Matrix(std::initializer_list<edge>const&E)noexcept:Matrix(){
            for (auto &&e : E){
                matrix[e.beg-1][e.end-1]=e.weight;
                // std::cout<<e.beg<<' '<<e.end<<' '<<e.weight<<std::endl;
            }
        }
        int& get(int i,int j){
            return matrix[i][j];
        }
        Matrix()noexcept{
            for(int i=0;i<size;++i){
                for(int j=0;j<size;++j){
                    matrix[i][j]=0;
                }
            }
        }
        void show(){
            for(size_t i = 0; i <size;++i){
                for(size_t j=0;j<size;++j){
                    std::cout<<matrix[i][j]<<' ';
                }std::cout<<std::endl;
            }
        }
        bool isLinked(int i,int j){
            return matrix[i][j];
        }
        // Matrix()noexcept:nodes(Vec<T>(size)){}
        Matrix& addEdge(int i,int j,int weight=1){
            matrix[i][j]=weight;
        }
};
int main(){
    // int m[8][8]={
    //     0,0,1,0,0,0,0,0,
    //     1,0,0,0,0,0,0,0,
    //     0,1,0,0,0,0,0,0,
    //     0,0,0,0,0,0,0,1,
    //     0,0,0,1,0,0,0,0,
    //     0,0,0,0,1,0,0,0,
    //     0,0,0,0,0,1,0,0,
    //     0,0,0,0,0,0,1,0
    // };
    Matrix<7>m=Matrix<7>{
        {1,2},{1,4},
        {2,3},
        {3,1},{3,4},{3,5},
        {4,3},{4,5},
        {6,5},{6,7},
        {7,5},{7,6}
    };
    m.show();
    Warshall(m,true);
    // m.show();
    return 0;
}